; include file
#dontinclude


; need to figure out revision
; single version for 4 channel






function	sid_playmusic	sid_playmusic_addr,sid_playmusic_play2,sid_playmusic_speed,sid_playmusic_loopcnt
rem	sid_playmusic( musicaddr.w , play.b , speed.b , loops.b )
rem	
rem	
rem	

def	sid_playmusic_play2	byte
ref	sid_playmusic_addr	word
ref	sid_playmusic_speed	byte
ref	sid_playmusic_loopcnt	byte


sid_playmusic
	orcc	#$50
	ldd	sid_playmusic_addr
	std	sid_playmusic_pos
	std	sid_playmusic_rpt


;reset song
	lda	#0
	sta	sid_playmusic_cnt
	sta	sid_playmusic_delta
	sta	sid_playmusic_delay
	lda	sid_playmusic_play2
	sta	sid_playmusic_play	;start play cmd
	lda	#227
	sta	sid_attackrel1
	lda	#251
	sta	sid_attackrel2
	sta	sid_attackrel3
	sta	sid_attackrel4
	sta	sid_attackrel5

;set sid clock
	ldx	#sid_clock_0
	lda	#48
	sta	0,x
	sta	1,x
	sta	3,x
	sta	4,x
	clr	5,x
	lda	#58
	sta	2,x

	ldx	#sid_clock_1
	lda	#48
	sta	0,x
	sta	1,x
	sta	3,x
	sta	4,x
	clr	5,x
	lda	#58
	sta	2,x

	clr	sid_time_m
	clr	sid_time_s

	clr	sid_time_ms

; try to calculate actual song size
	clr	sid_time_cm
	clr	sid_time_cs



	andcc	#$ef


	rts


endfunction


;***********************************************************************************************************************************
function	sid_setchannel1	sid_playmusic_ctrl1
rem	sid_setchannel1( #%00000000.b )
rem	noise / pulse / saw / triangle / test / ring mod / sync / gate
rem	gate must be on to produce any noise at all
rem	
ref	sid_playmusic_ctrl1	byte

sid_setchannel1

	rts

endfunction



;***********************************************************************************************************************************
function	sid_setchannel2	sid_playmusic_ctrl2
rem	sid_setchannel2( #%00000000.b )
rem	noise / pulse / saw / triangle / test / ring mod / sync / gate
rem	gate must be on to produce any noise at all
rem	

ref	sid_playmusic_ctrl2	byte

sid_setchannel2

	rts

endfunction




;***********************************************************************************************************************************
function	sid_setchannel3	sid_playmusic_ctrl3
rem	sid_setchannel3( #%00000000.b )
rem	noise / pulse / saw / triangle / test / ring mod / sync / gate
rem	gate must be on to produce any noise at all
rem
	
ref	sid_playmusic_ctrl3	byte

sid_setchannel3

	rts

endfunction


;***********************************************************************************************************************************
function	sid_setmodevol	sid_playmusic_mvol
rem	sid_setmodevol( #%00000000.b )
rem	
rem	off / hp / bp / lp / [ v3 / v2 / v1 / v0 ] volume 0-15
rem	

ref	sid_playmusic_mvol	byte

sid_setmodevol

	rts

endfunction



;***********************************************************************************************************************************
function	sid_setresfilter	sid_playmusic_resfilter
rem	sid_setresfilter( #%00000000.b )
rem	
rem	
rem	

ref	sid_playmusic_resfilter	byte

sid_setresfilter

	rts

endfunction

;*************************************************************************************************************************************


function	sid_settings	sid_file16
def	sid_file16	word
rem	sid_settings( 16byteheader.w )
rem	loads saved settings from file system and applies it
rem	


sid_settings


	clr	sid_time_s
	clr	sid_time_m
	clr	sid_time_ms

	clr	sid_time_cs
	clr	sid_time_cm




	ldu	sid_file16
	lda	0,u
	cmpa	#88
	lbne	sid_settings_exit

	lda	1,u
	sta	sid_playmusic_speed
	lda	2,u
	sta	sid_playmusic_loopcnt
	lda	3,u
	sta	sid_playmusic_ctrl1
	lda	4,u
	sta	sid_playmusic_ctrl2
	lda	5,u
	sta	sid_playmusic_ctrl3
	lda	6,u
	sta	sid_playmusic_ctrl4
	lda	7,u
	sta	sid_playmusic_ctrl5

	lda	8,u
	sta	sid_playmusic_fh
	lda	9,u
	sta	sid_playmusic_fl



	lda	sid_slot
	sta	$ff7f
	lda	9,u
	sta	$ff55
	lda	8,u
	sta	$ff56

	lda	sid_slot1
	sta	$ff7f
	lda	9,u
	sta	$ff55
	lda	8,u
	sta	$ff56



	lda	10,u
	anda	#15
	lsla
	lsla
	lsla
	lsla
	sta	sid_playmusic_res



	lda	11,u
	anda	#112
	sta	sid_playmusic_hbl

	lda	11,u
	anda	#7
	sta	sid_playmusic_fm


;timers
	lda	12,u
	sta	sid_time_cm
	lda	13,u
	sta	sid_time_cs



	lda	sid_slot
	sta	$ff7f
	lda	sid_playmusic_res
	adda	sid_playmusic_fm
	sta	$ff57

	lda	sid_playmusic_mvol
	adda	sid_playmusic_hbl
	sta	$ff58


	lda	sid_slot1
	sta	$ff7f
	lda	sid_playmusic_res
	adda	sid_playmusic_fm
	sta	$ff57
	lda	sid_playmusic_mvol
	adda	sid_playmusic_hbl
	sta	$ff58

	lda	boot_slot
	sta	$ff7f

sid_settings_exit

	rts
endfunction








;**********************************************************************************************************************************

function	sid_chip	sid_chip_tvout
rem	sid_chip( tv_out_enable.b )
rem	enables sid chip player version 1.0
rem	value of 1 hooks the mux bit for tv out
rem	mpiboot=1 for cart
rem	time_s , time_m  can be used as real clock mins and seconds for game



def	sid_chip_tvout	byte
def	sid_playmusic_addr	word
def	sid_playmusic_speed	byte
def	sid_playmusic_play	byte
def	sid_playmusic_pos	word
def	sid_playmusic_rpt	word
def	sid_playmusic_mvol	byte
def	sid_playmusic_cnt	byte
def	sid_playmusic_delta	byte
def	sid_playmusic_delay	byte


def	boot_slot	byte
def	sid_slot	byte
def	sid_slot1	byte

def	sid_playmusic_loopcnt	byte
def	sid_playmusic_gate1	byte
def	sid_playmusic_gate2	byte
def	sid_playmusic_gate3	byte
def	sid_playmusic_gate4	byte
def	sid_playmusic_gate5	byte

def	sid_playmusic_comgate1	byte
def	sid_playmusic_comgate2	byte
def	sid_playmusic_comgate3	byte
def	sid_playmusic_comgate4	byte
def	sid_playmusic_comgate5	byte

def	sid_playmusic_ctrl1	byte
def	sid_playmusic_ctrl2	byte
def	sid_playmusic_ctrl3	byte
def	sid_playmusic_ctrl4	byte
def	sid_playmusic_ctrl5	byte

def	sid_playmusic_drum	byte
def	sid_playmusic_resfilter	byte


def	sid_attackrel1	byte
def	sid_attackrel2	byte
def	sid_attackrel3	byte
def	sid_attackrel4	byte
def	sid_attackrel5	byte




def	sid_perc_freq	word


def	sid_playmusic_res	byte
def	sid_playmusic_fl	byte
def	sid_playmusic_fh	byte
def	sid_playmusic_hbl	byte
def	sid_playmusic_fm	byte

def	sid_clock_0	string	10
def	sid_clock_1	string	10

def	sid_time_m	byte
def	sid_time_s	byte
def	sid_time_ms	byte

def	sid_time_cm	byte
def	sid_time_cs	byte

def	sid_percussion_chan	word
def	sid_percussion_on	byte

def	time_s	byte
def	time_m	byte


def	sid_vol	byte


;mml sfx channel
def	sid_delta3	byte
def	sid_oct3	byte
def	sid_len3	byte
def	sid_ins3	byte
def	sid_spd3	byte
def	sid_pulse3	word

def	sid_p_address3	word
def	sid_s_address3	word
def	sid_r_address3	word
def	sid_playback3	byte

def	sid_gate3	byte
def	sid_com3	byte
def	sid_playcnt3	byte
def	sid_delay3	byte
def	sid_loop3	byte
def	sid_sharp	byte



def	channel_use1	byte
def	channel_use2	byte
def	channel_use3	byte

def	channel_len1	byte
def	channel_len2	byte
def	channel_len3	byte

def	channel_gate1	byte
def	channel_gate2	byte
def	channel_gate3	byte

def	channel_cgate1	byte
def	channel_cgate2	byte
def	channel_cgate3	byte


def	channel_freq1	word
def	channel_freq2	word
def	channel_freq3	word



sid_playspeed
	fcb	0,0
	fcb	0,1
	fcb	1,1
	fcb	1,2
	fcb	2,2
	fcb	2,3
	fcb	3,3
	fcb	3,4
	fcb	4,4
	fcb	5,5
	fcb	6,6
	fcb	7,7
	fcb	8,8
	fcb	9,9
	fcb	10,10
	fcb	11,11
	fcb	12,12
	fcb	13,13
	fcb	14,14
	fcb	15,15
	fcb	16,16
	fcb	17,17
	fcb	18,18
	fcb	19,19
	fcb	20,20

sid_tones
	fdb	274,291,308,326,346,366,388,411,435,461,489,518	;oct 0
	fdb	549,581,616,652,691,732,776,822,871,923,978,1036	;oct 1
	fdb	1097,1163,1232,1305,1383,1465,1552,1644,1742,1845,1955,2071	;oct 2
	fdb	2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143	;oct 3
	fdb	4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286	;oct 4
	fdb	8779,9301,9854,10440,11060,11718,12415,13153,13935,14764,15642,16572	;oct 5
	fdb	17557,18601,19709,20897,22121,23436,24830,26306,27871,29528,31234,33144	;oct 6
	fdb	35115,37203,39415,41759,44242,46873,49660,52613,55741,59056,62567,65535	;oct 7 tone b7 out of range

sid_lentable
	fcb	248,248,248
	fcb	249,249,249
	fcb	250,250,250,250,250
	fcb	251,251,251,251,251		;16

	fcb	252,252,252,252,252,252,252,252
	fcb	252,252,252,252,252,252,252,252	;16

	fcb	253,253,253,253,253,253,253,253
	fcb	253,253,253,253,253,253,253,253
	fcb	253,253,253,253,253,253,253,253
	fcb	253,253,253,253,253,253,253,253	;32

	fcb	254,254,254,254,254,254,254,254
	fcb	254,254,254,254,254,254,254,254
	fcb	254,254,254,254,254,254,254,254
	fcb	254,254,254,254,254,254,254,254	;64
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;96
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;
	fcb	254,254,254,254,254,254,254,254	;128


sid_notetable
	fcb	9,11,0,2,4,5,7,9



sid_speedtable
	fcb	250,251,252,253



sid_chip
	orcc	#$50	;kill interupt





;set sid clock
	ldx	#sid_clock_0
	lda	#48
	sta	0,x
	sta	1,x
	sta	3,x
	sta	4,x
	clr	5,x
	lda	#58
	sta	2,x

	ldx	#sid_clock_1
	lda	#48
	sta	0,x
	sta	1,x
	sta	3,x
	sta	4,x
	clr	5,x
	lda	#58
	sta	2,x

	clr	sid_time_m
	clr	sid_time_s
	clr	sid_time_ms

	clr	sid_time_cs
	clr	sid_time_cm



	clr	channel_use1
	clr	channel_use2
	clr	channel_use3
	clr	channel_len1
	clr	channel_len2
	clr	channel_len3
	clr	channel_gate1
	clr	channel_gate2
	clr	channel_gate3
	clr	channel_cgate1
	clr	channel_cgate2
	clr	channel_cgate3


	clr	sid_playmusic_play

;tv on
	if	b,sid_chip_tvout=#1
	lda	$ff01
	anda	#$f7
	sta	$ff01
	lda	$ff03
	ora	#8
	sta	$ff03
	lda	$ff23
	ora	#8
	sta	$ff23
	endif




	lda	$ff7f	;slot
	anda	#240
	sta	boot_slot	;boot slot

	lsra
	lsra
	lsra
	lsra
	anda	#12
	adda	boot_slot
	sta	sid_slot
;	adda	#1
	sta	sid_slot1

	lda	$ff7f
	sta	boot_slot	;fixed

	lda	sid_slot
	sta	$ff7f

; sid selected
	lda	#0
	sta	$ff44
	sta	$ff4b
	sta	$ff52
	lda	#127	;master volume 15 and filters set by default
	sta	$ff58

	lda	#65
	sta	sid_playmusic_ctrl1
	lda	#65
	sta	sid_playmusic_ctrl2
	lda	#65
	sta	sid_playmusic_ctrl3

	lda	#240
	sta	sid_playmusic_resfilter

;filter try
	ldd	#0
	sta	$ff55
	stb	$ff56

; set all pulse widths to square
	ldd	#2048
	sta	$ff43
	stb	$ff42

	ldd	#2048
	sta	$ff4a
	stb	$ff49

	ldd	#2048
	sta	$ff51
	stb	$ff50


	lda	#81
	sta	sid_playmusic_ctrl4
	lda	#97
	sta	sid_playmusic_ctrl5

	lda	#240
	sta	sid_playmusic_resfilter

;done setup


	lda	boot_slot
	sta	$ff7f	;mpi slot 0 of 0-3

	lda	#15
	sta	sid_playmusic_mvol	;store master volume
	clr	sid_playmusic_play	;not playing anything




	ldx	#sid_player_irq
	stx	$010d
	andcc	#$ef


	ldd	#$ff5f	;dummy write
	std	sid_percussion_chan
	lda	#1
	sta	sid_percussion_on

;sfx mml channel
	lda	#2
	sta	sid_oct3	;starting octave
	lda	#4
	sta	sid_len3	;starting note sizes
	clr	sid_gate3
	clr	sid_delay3
	clr	sid_delta3
	clr	sid_spd3
	clr	sid_playback3	;not playing


	rts



;****************************************************************************************************************************************
;****************** sid player version 1.5 by smdreloaded


sid_player_irq




; update system clock
	ldd	$112	;sys clock
	addd	#1
	std	$112


;1 second
	inc	sid_time_ms
	if	b,sid_time_ms>#59
	clr	sid_time_ms
	endif


;real time clock
	if	b,sid_time_ms=#0
	inc	time_s
	if	b,time_s>#59
	clr	time_s
	inc	time_m
	if	b,time_m>#59
	clr	time_m
	endif
	endif
	endif





; clear sid gates
; gate 1 includes sfx channel


	ldb	sid_slot
	stb	$ff7f

	lda	sid_playmusic_hbl
	adda	sid_playmusic_mvol
	sta	$ff58




	com	channel_cgate1
	bmi	sid_notgate1
	lda	channel_gate1
	anda	#254
	sta	$ff44

sid_notgate1

	com	channel_cgate2
	bmi	sid_notgate2
	lda	channel_gate2
	anda	#254
	sta	$ff4b


sid_notgate2


	com	channel_cgate3
	bmi	sid_notgate3
	lda	channel_gate3
	anda	#254
	sta	$ff52

sid_notgate3


; release channels
	if	b,channel_len1>#0
	lda	channel_len1
	suba	#2
	sta	channel_len1
	endif
	if	b,channel_len2>#0
	lda	channel_len2
	suba	#2
	sta	channel_len2
	endif
	if	b,channel_len3>#0
	lda	channel_len3
	suba	#2
	sta	channel_len3
	endif

	if	b,channel_len1=#0	or	b,channel_len1>#128
	clr	channel_use1
	endif
	if	b,channel_len2=#0	or	b,channel_len2>#128
	clr	channel_use2
	endif
	if	b,channel_len3=#0	or	b,channel_len3>#128
	clr	channel_use3
	endif

; look at player
	if	b,sid_playmusic_play!#0

	if	b,sid_time_ms=#0
	inc	sid_time_s
	if	b,sid_time_s>#59
	clr	sid_time_s
	inc	sid_time_m
	if	b,sid_time_m>#59
	clr	sid_time_m
	endif
	endif

	endif


	if	b,sid_playmusic_cnt>#0
	dec	sid_playmusic_cnt
	else
	jsr	sid_playmusic_update	;jump to update
	endif
	endif

;player3 mml sfx channel
;	if	b,sid_playback3!#0
;	if	b,sid_playcnt3>#0
;	dec	sid_playcnt3
;	else
;	jsr	sid_playmml3	;jump to update
;	endif
;	endif


	lda	boot_slot
	sta	$ff7f	;mpi slot 1 of 0-3




	lda	$ff02	;ack irq
	rti
; return to code




sid_playmml3

; sort out play speed
	ldx	#sid_playspeed
	ldb	#2
	lda	sid_spd3
	mul
	addb	sid_delta3
	leax	d,x

	lda	,x
	sta	sid_playcnt3
	inc	sid_delta3
	if	b,sid_delta3>#1
	clr	sid_delta3
	endif

	lda	sid_delay3
	beq	sid_playmusic_deltagood3
	dec	sid_delay3
	rts	;no play yet

sid_playmusic_deltagood3
	ldx	sid_p_address3	;song pos

sid_play_process3
	ldu	#sid_tones
	ldy	#sid_notetable

;note process
	lda	0,x
	lbeq	sid_play_done3


;octave change
	if	b,(0,x)=#79	;octave
	lda	1,x
	suba	#48

	sta	sid_oct3
	leax	2,x
	lbra	sid_play_process3
	endif

;length change
	if	b,(0,x)=#76	;length change
	jsr	sid_change_len
	sta	sid_len3
	lbra	sid_play_process3
	endif

;pause len
	if	b,(0,x)=#80	;length change
	jsr	sid_change_len
	sta	sid_delay3
	stx	sid_p_address3
	rts

	endif

;tempo  change
	if	b,(0,x)=#84	;tempo change
	lda	1,x
	suba	#48
	sta	sid_spd3
	leax	2,x
	lbra	sid_play_process3
	endif

;instrument change
	if	b,(0,x)=#73
	lda	1,x
	suba	#48
	sta	sid_ins3	;save instrument
	lsla
	lsla
	lsla
	lsla
	adda	#1
	sta	sid_gate3
	leax	2,x
	lbra	sid_play_process3
	endif

;volume change 0-9
	if	b,(0,x)=#86	b,(2,x)>#64	;0-9 range
	lda	1,x
	suba	#48
	sta	sid_vol
	sta	$ff58	;volume reg
	leax	2,x
	lbra	sid_play_process3
	endif
;volume change 10-15
	if	b,(0,x)=#86	b,(1,x)=#49	b,(2,x)<#54
	lda	2,x
	suba	#48
	adda	#10
	sta	sid_vol
	sta	$ff58	;volume reg
	leax	3,x
	lbra	sid_play_process3
	endif

;play note
	if	b,(0,x)=>#65	b,(0,x)=<#71
; sharp or not?
	clr	sid_sharp
	if	b,(1,x)=#35
	lda	#1
	sta	sid_sharp
	endif
;flat or not
	if	b,(1,x)=#45	b,(0,x)!#67
	lda	#255	;-1
	sta	sid_sharp
	endif

	ldb	#24	;12 word values
	lda	sid_oct3
	mul
	leau	d,u
	ldb	0,x
	subb	#65
	lda	b,y
	adda	sid_sharp
	ldb	#2
	mul
	leau	d,u
	lda	0,u
	ldb	1,u
	sta	$ff4f	;frequency
	stb	$ff4e
	ldy	#sid_lentable
	ldb	sid_len3
	lda	b,y	;length
	sta	$ff54	;sus release
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	sid_gate3
	anda	#254
	adda	#1
	sta	sid_gate3
	sta	$ff52	;note away
	clr	sid_com3

	if	b,sid_sharp!#0
	leax	1,x
	endif

	leax	1,x
	lda	sid_len3
	sta	sid_delay3
	stx	sid_p_address3
	rts
	endif

;not found
	leax	1,x
	
	lbra	sid_play_process3
;****************************************************************************************************************************************************


sid_play_done3
	if	b,sid_loop3=#1
	ldd	sid_r_address3
	std	sid_p_address3
	rts
	else
	ldd	sid_s_address3
	std	sid_p_address3
	clr	sid_playback3
	rts
	endif
	rts


;************************************************change length jsr
;***********************************************returns value on a
sid_change_len

	if	b,(1,x)=#49	b,(2,x)=#48	;p10
	lda	#2
	leax	3,x
	rts
	endif


	if	b,(1,x)=#49	b,(2,x)=#46	;1 yes dot
	lda	#47
	leax	3,x
	rts
	endif
	if	b,(1,x)=#49	b,(2,x)!#46	b,(2,x)!#54	;1 no dot and not 16
	lda	#31
	leax	2,x
	rts
	endif

	if	b,(1,x)=#50	b,(2,x)=#46	;2 yes dot
	lda	#23
	leax	3,x
	rts
	endif
	if	b,(1,x)=#50	b,(2,x)!#46	;2 no dot
	lda	#15
	leax	2,x
	rts
	endif

	if	b,(1,x)=#51	b,(2,x)=#46	;3 yes dot
	lda	#17
	leax	3,x
	rts
	endif
	if	b,(1,x)=#51	b,(2,x)!#46	b,(2,x)!#50	;3 no dot and not 32
	lda	#11
	leax	2,x
	rts
	endif

	if	b,(1,x)=#52	b,(2,x)=#46	;4 yes dot
	lda	#11
	leax	3,x
	rts
	endif
	if	b,(1,x)=#52	b,(2,x)!#46	;4 no dot
	lda	#7
	leax	2,x
	rts
	endif

	if	b,(1,x)=#56	b,(2,x)=#46	;8 yes dot
	lda	#5
	leax	3,x
	rts
	endif
	if	b,(1,x)=#56	b,(2,x)!#46	;8 no dot
	lda	#3
	leax	2,x
	rts
	endif

; l16
	if	b,(1,x)=#49	b,(2,x)=#54
	lda	#1
	leax	3,x
	rts
	endif

; l32
	if	b,(1,x)=#51	b,(2,x)=#50
	lda	#0
	leax	3,x
	rts
	endif

;fucked up string
	leax	1,x
	clra
	rts










sid_playmusic_update


; sort out play speed
	ldx	#sid_playspeed
	ldb	#2
	lda	sid_playmusic_speed
	mul
	addb	sid_playmusic_delta
	leax	d,x

	lda	,x
	sta	sid_playmusic_cnt
	inc	sid_playmusic_delta
	if	b,sid_playmusic_delta>#1
	clr	sid_playmusic_delta
	endif



; update music look at delta timer 2

	lda	sid_playmusic_delay
	beq	sid_playmusic_deltagood
	dec	sid_playmusic_delay
	rts	;no play yet

sid_playmusic_deltagood







	ldx	sid_playmusic_pos	;song pos
	ldu	#sid_lentable

sid_playmusic_process

; subtract lengths and free up channels


	ldd	,x++	;advance it

	cmpa	#12	;its a repeat looper locater
	lbeq	sid_playmusic_repeatset	;new delta counter

	cmpa	#13	;1 byte delay
	lbeq	sid_playmusic_setdelay	;new wait

	cmpa	#14
	lbeq	sid_playmusic_resetsng


; 3 percussions on z80 side
	cmpa	#9
	lbeq	sid_lib_perc1	;chan perc
	cmpa	#10
	lbeq	sid_lib_perc2	;chan perc
	cmpa	#11
	lbeq	sid_lib_perc3	;chan perc


	cmpa	#15
	lbeq	sid_setchan1	;chan b left
	cmpa	#16
	lbeq	sid_setchan2	;chan c left

;trash channel
	cmpa	#19
	lbeq	sid_setchan5	;dead channel

	cmpa	#17
	lbeq	sid_setchan3	;chan d right
	cmpa	#18
	lbeq	sid_setchan4	;chan e right


	lbra	sid_playmusic_process





;******************************************************************************************
sid_playmusic_setdelay

	stx	sid_playmusic_pos	;sty spos
	stb	sid_playmusic_delay
	rts



;*********************************************************************************************
; repeat locator
sid_playmusic_repeatset
	stx	sid_playmusic_rpt	;song repeater set
	lbra	sid_playmusic_process


;********************************************************************************************
; reset
sid_playmusic_resetsng
	ldx	sid_playmusic_rpt
	stx	sid_playmusic_pos


;check loop hmany times
	if	b,sid_playmusic_loopcnt!#0
	lda	sid_playmusic_loopcnt
	suba	#1
	sta	sid_playmusic_loopcnt

	if	b,sid_playmusic_loopcnt=#0
	clr	sid_playmusic_play
	endif
	endif


	if	b,sid_playmusic_play=#1
	clr	sid_playmusic_play	;play only once
	endif

	rts



sid_setchan1
; set frequency chan 1


	lda	,x+	;note
	suba	#12	;calibration
	ldy	#sid_tones
	ldb	#2
	mul
	leay	d,y
	ldd	0,y
	std	sid_perc_freq	;frequence note

	jsr	sid_find_channel

;miss it
	if	b,sid_channel=#0
	leax	1,x
	lbra	sid_playmusic_process
	endif
;hit it

	if	b,sid_channel=#1
	lda	#1
	sta	channel_use1	;lock it up
	ldd	sid_perc_freq
	sta	$ff41
	stb	$ff40
	lda	#$0c
	sta	$ff45	;attack/delay
	lda	,x+	;length of note
	sta	channel_len1

	ldb	a,u
	stb	$ff46	;sus vol/ release r
	lda	sid_playmusic_ctrl2
	sta	channel_gate1	;saved
	sta	$ff44	;note set
	clr	channel_cgate1	;com
	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#2
	lda	#1
	sta	channel_use2	;lock it up
	ldd	sid_perc_freq
	sta	$ff48
	stb	$ff47
	lda	#$0c
	sta	$ff4c	;attack/delay
	lda	,x+	;length of note
	sta	channel_len2
	ldb	a,u
	stb	$ff4d	;sus vol/ release r
	lda	sid_playmusic_ctrl2
	sta	channel_gate2	;saved
	sta	$ff4b	;note set
	clr	channel_cgate2	;com
	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#3
	lda	#1
	sta	channel_use3	;lock it up
	ldd	sid_perc_freq
	sta	$ff4f
	stb	$ff4e
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	,x+	;length of note
	sta	channel_len3
	ldb	a,u
	stb	$ff54	;sus vol/ release r
	lda	sid_playmusic_ctrl2
	sta	channel_gate3	;saved
	sta	$ff52	;note set
	clr	channel_cgate3	;com


	lbra	sid_playmusic_process
	endif

	leax	1,x
	lbra	sid_playmusic_process




sid_setchan2
; set frequency chan 2


	lda	,x+	;note
	suba	#12	;calibration
	ldy	#sid_tones
	ldb	#2
	mul
	leay	d,y
	ldd	0,y
	std	sid_perc_freq	;frequence note

	jsr	sid_find_channel

;miss it
	if	b,sid_channel=#0
	leax	1,x
	lbra	sid_playmusic_process
	endif
;hit it

	if	b,sid_channel=#1
	lda	#1
	sta	channel_use1	;lock it up
	ldd	sid_perc_freq
	sta	$ff41
	stb	$ff40
	lda	#$0c
	sta	$ff45	;attack/delay
	lda	,x+	;length of note
	sta	channel_len1
	ldb	a,u
	stb	$ff46	;sus vol/ release r
	lda	sid_playmusic_ctrl3
	sta	channel_gate1	;saved
	sta	$ff44	;note set
	clr	channel_cgate1	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#2
	lda	#1
	sta	channel_use2	;lock it up
	ldd	sid_perc_freq
	sta	$ff48
	stb	$ff47
	lda	#$0c
	sta	$ff4c	;attack/delay
	lda	,x+	;length of note
	sta	channel_len2
	ldb	a,u
	stb	$ff4d	;sus vol/ release r
	lda	sid_playmusic_ctrl3
	sta	channel_gate2	;saved
	sta	$ff4b	;note set
	clr	channel_cgate2	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#3
	lda	#1
	sta	channel_use3	;lock it up
	ldd	sid_perc_freq
	sta	$ff4f
	stb	$ff4e
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	,x+	;length of note
	sta	channel_len3
	ldb	a,u
	stb	$ff54	;sus vol/ release r
	lda	sid_playmusic_ctrl3
	sta	channel_gate3	;saved
	sta	$ff52	;note set
	clr	channel_cgate3	;com

	lbra	sid_playmusic_process
	endif

	leax	1,x
	lbra	sid_playmusic_process





sid_setchan3
; set frequency chan 3


	lda	,x+	;note
	suba	#12	;calibration
	ldy	#sid_tones
	ldb	#2
	mul
	leay	d,y
	ldd	0,y
	std	sid_perc_freq	;frequence note

	jsr	sid_find_channel

;miss it
	if	b,sid_channel=#0
	leax	1,x
	lbra	sid_playmusic_process
	endif
;hit it

	if	b,sid_channel=#1
	lda	#1
	sta	channel_use1	;lock it up
	ldd	sid_perc_freq
	sta	$ff41
	stb	$ff40
	lda	#$0c
	sta	$ff45	;attack/delay
	lda	,x+	;length of note
	sta	channel_len1
	ldb	a,u
	stb	$ff46	;sus vol/ release r
	lda	sid_playmusic_ctrl4
	sta	channel_gate1	;saved
	sta	$ff44	;note set
	clr	channel_cgate1	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#2
	lda	#1
	sta	channel_use2	;lock it up
	ldd	sid_perc_freq
	sta	$ff48
	stb	$ff47
	lda	#$0c
	sta	$ff4c	;attack/delay
	lda	,x+	;length of note
	sta	channel_len2
	ldb	a,u
	stb	$ff4d	;sus vol/ release r
	lda	sid_playmusic_ctrl4
	sta	channel_gate2	;saved
	sta	$ff4b	;note set
	clr	channel_cgate2	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#3
	lda	#1
	sta	channel_use3	;lock it up
	ldd	sid_perc_freq
	sta	$ff4f
	stb	$ff4e
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	,x+	;length of note
	sta	channel_len3
	ldb	a,u
	stb	$ff54	;sus vol/ release r
	lda	sid_playmusic_ctrl4
	sta	channel_gate3	;saved
	sta	$ff52	;note set
	clr	channel_cgate3	;com

	lbra	sid_playmusic_process
	endif

	leax	1,x
	lbra	sid_playmusic_process





sid_setchan4
; set frequency chan 4


	lda	,x+	;note
	suba	#12	;calibration
	ldy	#sid_tones
	ldb	#2
	mul
	leay	d,y
	ldd	0,y
	std	sid_perc_freq	;frequence note

	jsr	sid_find_channel

;miss it
	if	b,sid_channel=#0
	leax	1,x
	lbra	sid_playmusic_process
	endif
;hit it

	if	b,sid_channel=#1
	lda	#1
	sta	channel_use1	;lock it up
	ldd	sid_perc_freq
	sta	$ff41
	stb	$ff40
	lda	#$0c
	sta	$ff45	;attack/delay
	lda	,x+	;length of note
	sta	channel_len1
	ldb	a,u
	stb	$ff46	;sus vol/ release r
	lda	sid_playmusic_ctrl5
	sta	channel_gate1	;saved
	sta	$ff44	;note set
	clr	channel_cgate1	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#2
	lda	#1
	sta	channel_use2	;lock it up
	ldd	sid_perc_freq
	sta	$ff48
	stb	$ff47
	lda	#$0c
	sta	$ff4c	;attack/delay
	lda	,x+	;length of note
	sta	channel_len2
	ldb	a,u
	stb	$ff4d	;sus vol/ release r
	lda	sid_playmusic_ctrl5
	sta	channel_gate2	;saved
	sta	$ff4b	;note set
	clr	channel_cgate2	;com

	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#3
	lda	#1
	sta	channel_use3	;lock it up
	ldd	sid_perc_freq
	sta	$ff4f
	stb	$ff4e
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	,x+	;length of note
	sta	channel_len3
	ldb	a,u
	stb	$ff54	;sus vol/ release r
	lda	sid_playmusic_ctrl5
	sta	channel_gate3	;saved
	sta	$ff52	;note set
	clr	channel_cgate3	;com

	lbra	sid_playmusic_process
	endif

	leax	1,x
	lbra	sid_playmusic_process



sid_setchan5
; set frequency chan 4
	leax	2,x
	lbra	sid_playmusic_process



;share channel 1

sid_lib_perc1
	ldd	#15000
	std	sid_perc_freq
;	sta	$ff41
;	stb	$ff40
	bra	sid_lib_perchit

sid_lib_perc2
	ldd	#10000
	std	sid_perc_freq
;	sta	$ff41
;	stb	$ff40
	bra	sid_lib_perchit

sid_lib_perc3
	ldd	#2500
	std	sid_perc_freq

;	sta	$ff41
;	stb	$ff40
	bra	sid_lib_perchit

sid_lib_perchit



;	lbra	sid_playmusic_process
;'***************hack

; channel 0 available?

	jsr	sid_find_channel

	if	b,sid_channel=#0


	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#1
	lda	#1
	sta	channel_use1	;lock it up
	ldd	sid_perc_freq
	std	channel_freq1
	sta	$ff41
	stb	$ff40
	lda	#$0c
	sta	$ff45	;attack/delay
	lda	#2	;length of note
	sta	channel_len1
	ldb	a,u
	stb	$ff46	;sus vol/ release r
	lda	sid_playmusic_ctrl1
	sta	channel_gate1	;saved
	sta	$ff44	;note set
	clr	channel_cgate1	;com
	lbra	sid_playmusic_process
	endif

	if	b,sid_channel=#2
	lda	#1
	sta	channel_use2	;lock it up
	ldd	sid_perc_freq
	std	channel_freq2
	sta	$ff47
	stb	$ff48
	lda	#$0c
	sta	$ff4c	;attack/delay
	lda	#2	;length of note
	sta	channel_len2
	ldb	a,u
	stb	$ff4d	;sus vol/ release r
	lda	sid_playmusic_ctrl1
	sta	channel_gate2	;saved
	sta	$ff4b	;note set
	clr	channel_cgate2	;com
	lbra	sid_playmusic_process
	endif
	if	b,sid_channel=#3
	lda	#1
	sta	channel_use3	;lock it up
	ldd	sid_perc_freq
	std	channel_freq3
	sta	$ff4e
	stb	$ff4f
	lda	#$0c
	sta	$ff53	;attack/delay
	lda	#2	;length of note
	sta	channel_len3
	ldb	a,u
	stb	$ff54	;sus vol/ release r
	lda	sid_playmusic_ctrl1
	sta	channel_gate3	;saved
	sta	$ff52	;note set
	clr	channel_cgate3	;com
	lbra	sid_playmusic_process
	endif

	lbra	sid_playmusic_process




;************************************************************************************************
def	sid_channel	byte

sid_find_channel
	clr	sid_channel


;check if frequency used already or running..... if so dont play another

	if	w,sid_perc_freq=channel_freq3	b,channel_use3=#1

	rts
	endif
	if	w,sid_perc_freq=channel_freq2	b,channel_use2=#1

	rts
	endif
	if	w,sid_perc_freq=channel_freq1	b,channel_use1=#1

	rts
	endif

;ok we still here?

	if	b,channel_use3=#0
	lda	#3
	sta	sid_channel
	endif
	if	b,channel_use2=#0
	lda	#2
	sta	sid_channel
	endif
	if	b,channel_use1=#0
	lda	#1
	sta	sid_channel
	endif





	rts




def	sid_foundperc	byte

;	clr	channel_use1
;	clr	channel_use2
;	clr	channel_use3
;	clr	channel_len1
;	clr	channel_len2
;	clr	channel_len3
;	clr	channel_gate1
;	clr	channel_gate2
;	clr	channel_gate3




endfunction










function	playsid_mml	playsid_mml_ins,playsid_mml_play,playsid_mml_spd,playsid_mml_addr
rem	playsid_mml( instrument.b , playback.b , speed.b , address.w )
rem	
rem	
rem	plays back mml over channel 3 and cuts music out
def	playsid_mml_chan	byte
def	playsid_mml_ins	byte
def	playsid_mml_play	byte
def	playsid_mml_spd	byte
def	playsid_mml_addr	word


playsid_mml

	ldd	playsid_mml_addr
	std	sid_p_address3
	std	sid_s_address3
	std	sid_r_address3

	clr	sid_playcnt3
	clr	sid_delta3
	lda	playsid_mml_spd
	sta	sid_spd3	;speed setup


;setup instrument
	lda	playsid_mml_ins
	lsla
	lsla
	lsla
	lsla
	adda	#1
	sta	sid_gate3	;setup instrument


;last
	if	b,playsid_mml_play<#2
	clr	sid_loop3
	else
	lda	#1
	sta	sid_loop3
	endif

	if	b,playsid_mml_play!#0
	lda	#1
	sta	sid_playback3
	endif

	rts





endfunction











